﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace FlowBasis.Security.Passwords
{
    public class Sha512PasswordValidationService : IHashedPasswordValidationService
    {

        public bool ValidatePassword(string password, byte[] salt, byte[] passwordHash)
        {
            byte[] hash = this.ComputeHash(password, salt);
            if (hash.Length != passwordHash.Length)
                return false;

            for (int co = 0; co < passwordHash.Length; co++)
            {
                if (hash[co] != passwordHash[co])
                    return false;
            }

            return true;
        }

        public byte[] ComputeHash(string password, byte[] salt)
        {
            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

            MemoryStream bytesToHashStream = new MemoryStream();
            bytesToHashStream.Write(passwordBytes, 0, passwordBytes.Length);
            if (salt != null)
            {
                bytesToHashStream.Write(salt, 0, salt.Length);
            }

            bytesToHashStream.Position = 0;

            using (var sha512 = new SHA512Managed())
            {
                byte[] hash = sha512.ComputeHash(bytesToHashStream);
                return hash;
            }            
        }

        public byte[] GenerateSalt(int byteCount)
        {
            byte[] saltArray = new byte[byteCount];

            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(saltArray);

            return saltArray;
        }
    }
}
